/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
 * 
 * FILENAME
 *     NUC900_VPOST_LPL_LB064.c
 *
 * VERSION
 *     0.1 
 *
 * DESCRIPTION
 *
 *
 *
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *
 *
 *     
 * HISTORY
 *     2005.03.16		Created by Shih-Jen Lu
 *
 *
 * REMARK
 *     None
 *
 *
 **************************************************************************/
#include "wblib.h"
#include "NUC900_VPOST_Regs.h"
#include "NUC900_VPOST.h"
#ifdef	HAVE_LPL_LB064

#ifdef ECOS
cyg_handle_t	vpost_int_handle;
cyg_interrupt	vpost_int_holder;
#endif

static VPOST_T	_tLPL_LB064;

static void Delay(int nCnt)
{
	volatile int  loop;
	for (loop=0; loop<nCnt; loop++);
}

#if 0
static VOID vpostDisp_F_ISR(void)
{
    outpw(REG_LCM_INT_CS,inpw(REG_LCM_INT_CS) | VPOSTB_DISP_F_STATUS);
    vpostVAStartTrigger();
}
static VOID vpostUNDERRUN_ISR(void)
{
	outpw(REG_LCM_INT_CS,inpw(REG_LCM_INT_CS) | VPOSTB_UNDERRUN_INT);
}

static VOID vpostBUS_ERROR_ISR(void)
{
	outpw(REG_LCM_INT_CS,inpw(REG_LCM_INT_CS) | VPOSTB_BUS_ERROR_INT);
}
#ifdef ECOS
static cyg_uint32 vpostIntHandler(cyg_vector_t vector, cyg_addrword_t data)
#else
static VOID vpostIntHandler(void)
#endif
{
   /* clear VPOST interrupt state */
   UINT32 uintstatus;
   
   uintstatus = inpw(REG_LCM_INT_CS);
   if (uintstatus & VPOSTB_DISP_F_STATUS)  
      vpostDisp_F_ISR();
   else if (uintstatus & VPOSTB_UNDERRUN_INT)
      vpostUNDERRUN_ISR();
   else if (uintstatus & VPOSTB_BUS_ERROR_INT)
      vpostBUS_ERROR_ISR();

#ifdef ECOS
	return CYG_ISR_HANDLED;
#endif
}

static void vpostEnable_Int(void)
{
#ifdef ECOS
    cyg_interrupt_create(IRQ_LCD, 1, 0, vpostIntHandler, NULL, &_tLPL_LB064.vpost_int_handle, &_tLPL_LB064.vpost_int_holder);
    cyg_interrupt_attach(vpost_int_handle);
    cyg_interrupt_unmask(IRQ_LCD);
#else
    sysInstallISR(IRQ_LEVEL_1, IRQ_LCD, (PVOID)vpostIntHandler);
    /* enable VPOST interrupt */
    sysEnableInterrupt(IRQ_LCD);
#endif
    writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) | VPOSTB_DISP_INT_EN);
    writew(REG_LCM_INT_CS,readw(REG_LCM_INT_CS) | VPOSTB_UNDERRUN_EN | VPOSTB_DISP_F_EN);
}
#endif


INT vpostOSDInit_LPL_LB064(UINT16 ucOSDSrcType,UINT16 usxstart,UINT16 usystart,
											UINT16 usxend,UINT16 usyend,UINT16 usOSDPicWidth)
{

    vpostSetOSDSrc(ucOSDSrcType);
    
    vpostSetOSDBuffer();
    /*if (ucOSDSrcType != 0)
     	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) | ucOSDSrcType);
     else
     	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) & 0xffff0fff);//clear OSD SRC setting	
	*/
	vpostOSDSetWindow(usxstart,usystart,usxend,usyend);
     
	writew(REG_LCM_OSD_FBCTRL,0);//clear OSD STRIDE,FF setting
    if ((ucOSDSrcType==OSD_SRC_RGB888)||(ucOSDSrcType==OSD_SRC_RGB666))
    {
		writew(REG_LCM_OSD_FBCTRL,(usOSDPicWidth<<16) | usOSDPicWidth); //OSDFF~OSD_STRIDE
    }
    else if (ucOSDSrcType==OSD_SRC_RGB332)
    {
    	writew(REG_LCM_OSD_FBCTRL,((usOSDPicWidth/4)<<16) | (usOSDPicWidth/4)); //OSDFF~OSD_STRIDE
    }
    else{
        writew(REG_LCM_OSD_FBCTRL,((usOSDPicWidth/2)<<16) | (usOSDPicWidth/2)); //OSDFF~OSD_STRIDE
    }
    //vpostOSDScalingCtrl(1,0,0);
    
    return 0;
}








static VOID vpostSetCRTC_LPL_LB064(UINT16 usHorizontal,UINT16 usVertical,UINT16 ucVASrcType,UINT16 usPicWidth)
{   
	
	outpw(REG_LCM_CRTC_SIZE,0x020D0320); //CRTC_SIZE
    outpw(REG_LCM_CRTC_DEND,0x01E00280); //CRTC_DEND
    outpw(REG_LCM_CRTC_HR,0x02940284); //CRTC_HR
    outpw(REG_LCM_CRTC_HSYNC,0x02880298); //CRTC_HSYNC
    outpw(REG_LCM_CRTC_VR,0x01ec01ea); //CRTC_VR
    if ((ucVASrcType==VA_SRC_RGB888) || (ucVASrcType==VA_SRC_RGB666))
    {
  		outpw(REG_LCM_VA_FBCTRL,inpw(REG_LCM_VA_FBCTRL) &~0x7ff07ff | (usPicWidth<<16) | usPicWidth); //VAFF~VA_STRIDE
	}
	else
	{
		outpw(REG_LCM_VA_FBCTRL,inpw(REG_LCM_VA_FBCTRL) &~0x7ff07ff | ((usPicWidth/2)<<16) | (usPicWidth/2)); //VAFF~VA_STRIDE
	}
	    

}



INT vpostLCMInit_LPL_LB064(VA_CB_FUNC_T *fnCallBack,UINT16 ucVASrcType,UINT8 ucVADisMode,UINT16 usPicWidth,UINT8 ucROT90)
{
	UINT32 VA_FF;
	UINT32 VA_Sride;
	_tLPL_LB064.usDevWidth = 640;
	_tLPL_LB064.usDevHeight = 480;
	_tLPL_LB064.uCmdLow = 0;
	_tLPL_LB064.ucCmd16t18 = 0;
	_tLPL_LB064.uCmdBusWidth = 0;
	_tLPL_LB064.uDataBusWidth = VPOSTB_DATA16or18;
	_tLPL_LB064.ucMPU_Mode = 0;
	_tLPL_LB064.uMPU_ColorMode = VPOSTB_COLORTYPE_256K;
	_tLPL_LB064.ucDeviceType = VPOSTB_DEVICE_SYNC_HIGHCOLOR;
	_tLPL_LB064.fnDisplayCallBack = fnCallBack;
	
	outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) | VPOSTB_ENG_RST);
	Delay(100);
	outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) & ~VPOSTB_ENG_RST);
	Delay(100);
	
	
	/* set the display buffer (fetch from VA_BADDR0, if at single buffer mode)*/
	if (vpostSetVABuffer()<0)
		return ERR_NULL_BUF;
	
	/* set display mode */
	vpostSetDisplayMode(ucVADisMode);
	
	/* set display video source format */
	vpostSetVASrc(ucVASrcType);
	/*
	if (ucVASrcType!=0)
		outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) | ucVASrcType);
	else
		outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) & ~(7<<8));
	*/
	//18-bit,256k,80mode,mpu-based,cmd18-16L0
	
	
	//vpostSetDeviceCtrl(_tLPL_LB064);
	//outpw(REG_LCM_DEV_CTRL,0xA1C00004);
	//outpw(REG_LCM_DEV_CTRL,0x02E0000A);
	
	outpw(REG_LCM_DEV_CTRL,0x0);//set default value
	writew(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | _tLPL_LB064.uCmdLow 
												   | _tLPL_LB064.ucCmd16t18
												   | _tLPL_LB064.uCmdBusWidth
												   | _tLPL_LB064.uDataBusWidth
												   | _tLPL_LB064.ucMPU_Mode
												   | _tLPL_LB064.uMPU_ColorMode
												   | _tLPL_LB064.ucDeviceType );
	
	

	
	vpostSetCRTC_LPL_LB064(_tLPL_LB064.usDevWidth,_tLPL_LB064.usDevHeight,
						ucVASrcType,usPicWidth);
	
	/* set video stream frame buffer control */
	VA_FF = (plcdformatex->nScreenWidth)*(nBytesPixel)/4;//word unit
    VA_Sride = (plcdformatex->nScreenWidth)*(nBytesPixel)/4;//word unit
    outpw(REG_LCM_VA_FBCTRL,inpw(REG_LCM_VA_FBCTRL) &~0x7ff07ff | (VA_FF<<16) | VA_Sride);
						
	//vpostEnable_Int();
	return 0;
}



#endif	/* HAVE_SAMSUNG_80_18IT */